package org.c3p0.spring.boot.autoconfigure;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.c3p0.spring.boot.autoconfigure.properties.C3p0DataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @ClassName C3p0DataSourceAutoConfigure
 * @Description TODO
 * @Author Kx
 * @Date 2025/9/15 11:08
 * @Version 1.0
 */
// 标识为配置类
@Configuration
/**
 * 当ComboPooledDataSource.class存在classpath时则初始化配置类
 */
@ConditionalOnClass(ComboPooledDataSource.class)
/**
 * C3p0DataSourceAutoConfigure配置类会在DataSourceAutoConfiguration之前先加载
 */
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
/**
 * 将带有@ConfigurationProperties注解的类纳入Spring容器中管理,便于注入使用
 * DataSourceProperties绑定的是spring数据源连接属性
 * C3p0DataSourceProperties绑定的是c3p0连接池属性
 */
@EnableConfigurationProperties({DataSourceProperties.class, C3p0DataSourceProperties.class})
/**
 * springboot在 2.2 以后提供了 @ConfigurationPropertiesScan注解来扫描@ConfigurationProperties注解的类
 */
//@ConfigurationPropertiesScan("org.c3p0.spring.boot.autoconfigure.properties")
public class C3p0DataSourceAutoConfigure {
    @Autowired
    private C3p0DataSourceProperties c3p0DataSourceProperties;
    @Autowired
    private DataSourceProperties dataSourceProperties;

    @Bean
    /**
     * 如果spring容器不存在这个DataSource的Bean则初始化
    */
    @ConditionalOnClass
    public DataSource dataSource() throws Exception {
        // 初始化c3p0的连接池
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        // 判断数据源连接属性是否为空
        if (dataSourceProperties.getDriverClassName() != null) {
            // 设置数据源连接属性
            dataSource.setDriverClass(dataSourceProperties.getDriverClassName());
        }
        // 判断数据源的JDBC连接地址是否为空
        if (dataSourceProperties.getUrl() != null) {
            // 设置数据源的JDBC连接地址
            dataSource.setJdbcUrl(dataSourceProperties.getUrl());
        }
        // 判断数据源的用户名是否为空
        if (dataSourceProperties.getUsername() != null) {
            // 设置数据源的用户名
            dataSource.setUser(dataSourceProperties.getUsername());
        }
        // 判断数据源的密码是否为空
        if (dataSourceProperties.getPassword() != null) {
            // 设置数据源的密码
            dataSource.setPassword(dataSourceProperties.getPassword());
        }
        // 设置连接池最大连接数
        dataSource.setMaxPoolSize(c3p0DataSourceProperties.getMaxPoolSize());
        // 设置连接池最小连接数
        dataSource.setMinPoolSize(c3p0DataSourceProperties.getMinPoolSize());
        // 设置连接池初始连接数
        dataSource.setInitialPoolSize(c3p0DataSourceProperties.getInitialPoolSize());
        // 设置连接池空闲时间
        dataSource.setMaxIdleTime(c3p0DataSourceProperties.getMaxIdleTime());
        return dataSource;
    }
}
